#include "stdafx.h"
#include <Windows.h>
#include <tchar.h>
#include <time.h>
#include <stdio.h>	/* _snprintf */
#include <stdlib.h> /* _MAX_PATH */
#include <string.h> /* strrchr */
#include <DbgHelp.h>
#include "amCrashDump.h"
//------------------------------------------------------------------------------
typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(
	HANDLE	hProcess,
	DWORD	dwPid,
	HANDLE	fFile,
	MINIDUMP_TYPE	DumpType,
	CONST PMINIDUMP_EXCEPTION_INFORMATION	ExceptionParam,
	CONST PMINIDUMP_USER_STREAM_INFORMATION	UserStreamParam,
	CONST PMINIDUMP_CALLBACK_INFORMATION	CallbackParam );
//---------------------------------------------------------------------------

TMiniDumper::TMiniDumper( void )
{
	//::GetModuleFileName( NULL, s_szAppName, _MAX_PATH );
	::SetUnhandledExceptionFilter( TopLevelFilter );
}
TMiniDumper::~TMiniDumper( void )
{
	// nothing here nor there
    ::SetUnhandledExceptionFilter(NULL);
}
//------------------------------------------------------------------------------
LONG WINAPI TMiniDumper::TopLevelFilter(struct _EXCEPTION_POINTERS *pException )
{
	LONG ret = EXCEPTION_CONTINUE_SEARCH;
	HMODULE hDll = NULL;

	TCHAR szDumpPath[_MAX_PATH] = {0,};
    lstrcpy(szDumpPath, ModulePath().GetString());
	hDll = ::LoadLibrary( _T("DBGHELP.DLL") );

	SYSTEMTIME st;
	::GetLocalTime( &st );
	
	TCHAR szTail[_MAX_PATH] = {0,};
	wsprintf( szTail, _T("__%04d-%02d-%02d__%02d-%02d-%02d"),
		st.wYear, st.wMonth, st.wDay,
		st.wHour, st.wMinute, st.wSecond );
    lstrcat(szDumpPath, szTail);

	if (!hDll)
		return ret;

	MINIDUMPWRITEDUMP pfnDumpWriter = (MINIDUMPWRITEDUMP)::GetProcAddress( hDll, "MiniDumpWriteDump" );
	if (!pfnDumpWriter)
		return ret;

	::lstrcat( szDumpPath, _T(".dmp") );
	HANDLE hFile = ::CreateFile( szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
		CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
	if (INVALID_HANDLE_VALUE == hFile)
		return ret;

	MINIDUMP_EXCEPTION_INFORMATION ExceptionParam;
	ExceptionParam.ThreadId = ::GetCurrentThreadId();
	ExceptionParam.ExceptionPointers = pException;
	ExceptionParam.ClientPointers = FALSE;

	BOOL bResult = FALSE;
	bResult = pfnDumpWriter( ::GetCurrentProcess(), ::GetCurrentProcessId(),
		hFile, MiniDumpNormal, &ExceptionParam, NULL, NULL );

	if (bResult)
		ret = EXCEPTION_EXECUTE_FAULT;

	CloseHandle( hFile );
	return ret;
}
//------------------------------------------------------------------------------
// end of file
